View Javadoc
1 /* 2 * Scope: a generic MVC framework. 3 * Copyright (c) 2000-2002, The Scope team 4 * All rights reserved. 5 * 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 14 * Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * Neither the name "Scope" nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR 27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 29 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 * 35 * 36 * $Id: ListModel.java,v 1.12 2002/09/12 10:51:03 ludovicc Exp $ 37 */ 38 package org.scopemvc.model.collection; 39 40 41 import java.util.ArrayList; 42 import java.util.Collection; 43 import java.util.Iterator; 44 import java.util.List; 45 import java.util.ListIterator; 46 import org.apache.commons.logging.Log; 47 import org.apache.commons.logging.LogFactory; 48 import org.scopemvc.core.ModelChangeEvent; 49 import org.scopemvc.core.ModelChangeEventSource; 50 import org.scopemvc.core.Selector; 51 import org.scopemvc.model.basic.BasicModel; 52 53 /*** 54 * <P> 55 * 56 * A BasicModel wrapper for an <CODE>List</CODE> that can propagate changes to 57 * contained Models up the Model hierarchy. The list itself is exposed via the 58 * "list" property, however, changes to this list must be made through this 59 * class's public API in order to maintain the event propagation. </P> <P> 60 * 61 * By default ListModel registers itself as a listener to Models that are added 62 * to the list and deregisters when those Models are removed. This behaviour can 63 * be changed at creation so that ModelChangeEvent propagation is disabled. </P> 64 * 65 * @author <A HREF="mailto:haruki_zaemon@users.sourceforge.net">Simon Harris</A> 66 * @author <A HREF="mailto:smeyfroi@users.sourceforge.net">Steve Meyfroidt</A> 67 * @created 05 September 2002 68 * @version $Revision: 1.12 $ 69 */ 70 public class ListModel extends BasicModel implements List { 71 72 /*** 73 * TODO: describe of the Field 74 */ 75 public static final Selector LIST = Selector.fromString("list"); 76 77 // ----------------- for debug ----------------------- 78 79 /*** 80 * TODO: describe of the Field 81 */ 82 protected static final String TO_STRING_SEPARATOR = ", "; 83 /*** 84 * TODO: describe of the Field 85 */ 86 protected static final int TO_STRING_SEPARATOR_LENGTH = TO_STRING_SEPARATOR.length(); 87 88 private static final Log LOG = LogFactory.getLog(ListModel.class); 89 90 /*** 91 * TODO: describe of the Field 92 */ 93 protected List contents; 94 95 /*** 96 * TODO: describe of the Field 97 */ 98 protected boolean propagateModelChanges; 99 100 101 /*** 102 * Constructor for the ListModel object 103 */ 104 public ListModel() { 105 this(true, new ArrayList(10)); 106 } 107 108 109 /*** 110 * Constructor for the ListModel object 111 * 112 * @param inList TODO: Describe the Parameter 113 */ 114 public ListModel(List inList) { 115 this(true, inList); 116 } 117 118 119 /*** 120 * Constructor for the ListModel object 121 * 122 * @param inPropagateModelChanges TODO: Describe the Parameter 123 */ 124 public ListModel(boolean inPropagateModelChanges) { 125 propagateModelChanges = inPropagateModelChanges; 126 } 127 128 129 /*** 130 * Constructor for the ListModel object 131 * 132 * @param inPropagateModelChanges TODO: Describe the Parameter 133 * @param inList TODO: Describe the Parameter 134 */ 135 public ListModel(boolean inPropagateModelChanges, List inList) { 136 this(inPropagateModelChanges); 137 setList(inList); 138 } 139 140 141 /*** 142 * Gets the list 143 * 144 * @return The list value 145 */ 146 public List getList() { 147 return contents; 148 } 149 150 151 /*** 152 * Gets the size 153 * 154 * @return The size value 155 */ 156 public int getSize() { 157 if (contents == null) { 158 return 0; 159 } 160 return contents.size(); 161 } 162 163 164 /*** 165 * Gets the index of 166 * 167 * @param inValue TODO: Describe the Parameter 168 * @return The indexOf value 169 */ 170 public int getIndexOf(Object inValue) { 171 if (inValue == null) { 172 return -1; 173 } 174 return contents.indexOf(inValue); 175 } 176 177 178 /*** 179 * Gets the empty 180 * 181 * @return The empty value 182 */ 183 public boolean isEmpty() { 184 return getList().isEmpty(); 185 } 186 187 188 /*** 189 * TODO: document the method 190 * 191 * @param index TODO: Describe the Parameter 192 * @return TODO: Describe the Return Value 193 */ 194 public Object get(int index) { 195 return contents.get(index); 196 } 197 198 199 /*** 200 * Set contents to the passed Object list and fire a ModelChangeEvent. 201 * 202 * @param inContents The new list value 203 */ 204 public void setList(List inContents) { 205 206 if (propagateModelChanges) { 207 // Clear up old list if it contained any Models 208 if (contents != null) { 209 for (Iterator i = contents.iterator(); i.hasNext(); ) { 210 Object o = i.next(); 211 if (o instanceof ModelChangeEventSource) { 212 ((ModelChangeEventSource) o).removeModelChangeListener(this); 213 } 214 } 215 } 216 } 217 218 contents = inContents; 219 220 if (propagateModelChanges) { 221 // Register as listener to any Models in the new list 222 if (contents != null) { 223 for (Iterator i = contents.iterator(); i.hasNext(); ) { 224 Object o = i.next(); 225 if (o instanceof ModelChangeEventSource) { 226 ((ModelChangeEventSource) o).addModelChangeListener(this); 227 } 228 } 229 } 230 } 231 232 fireModelChange(ModelChangeEvent.VALUE_CHANGED, LIST); 233 } 234 235 236 /*** 237 * TODO: document the method 238 * 239 * @param index TODO: Describe the Parameter 240 * @param element TODO: Describe the Parameter 241 * @return TODO: Describe the Return Value 242 */ 243 public Object set(int index, Object element) { 244 if (LOG.isDebugEnabled()) { 245 LOG.debug("set: " + index + ", " + element); 246 } 247 248 Object oldValue = contents.get(index); 249 contents.set(index, element); 250 fireModelChange(VALUE_CHANGED, Selector.fromInt(index)); 251 252 if (propagateModelChanges) { 253 if (oldValue instanceof ModelChangeEventSource) { 254 ((ModelChangeEventSource) oldValue).removeModelChangeListener(this); 255 } 256 if (element instanceof ModelChangeEventSource) { 257 ((ModelChangeEventSource) element).addModelChangeListener(this); 258 } 259 } 260 261 return oldValue; 262 } 263 264 /*** 265 * TODO: document the method 266 * 267 * @return TODO: Describe the Return Value 268 */ 269 public String toString() { 270 271 if (contents == null) { 272 return ""; 273 } 274 275 StringBuffer result = new StringBuffer("("); 276 277 for (Iterator i = contents.iterator(); i.hasNext(); ) { 278 Object o = i.next(); 279 result.append(o == null ? "<null>" : o.toString()); 280 result.append(TO_STRING_SEPARATOR); 281 } 282 283 if (contents.size() > 0) { 284 result.setLength(result.length() - TO_STRING_SEPARATOR_LENGTH); 285 } 286 result.append(')'); 287 288 return result.toString(); 289 } 290 291 292 // -------------------------- implement List ------------------------------ 293 294 /*** 295 * TODO: document the method 296 * 297 * @return TODO: Describe the Return Value 298 */ 299 public Iterator iterator() { 300 return getList().iterator(); 301 } 302 303 304 /*** 305 * TODO: document the method 306 * 307 * @return TODO: Describe the Return Value 308 */ 309 public int size() { 310 return getList().size(); 311 } 312 313 314 /*** 315 * TODO: document the method 316 * 317 * @param a TODO: Describe the Parameter 318 * @return TODO: Describe the Return Value 319 */ 320 public Object[] toArray(Object a[]) { 321 return getList().toArray(a); 322 } 323 324 325 /*** 326 * TODO: document the method 327 * 328 * @param o TODO: Describe the Parameter 329 * @return TODO: Describe the Return Value 330 */ 331 public boolean contains(Object o) { 332 return getList().contains(o); 333 } 334 335 336 /*** 337 * TODO: document the method 338 * 339 * @param o TODO: Describe the Parameter 340 * @return TODO: Describe the Return Value 341 */ 342 public boolean remove(Object o) { 343 int i = indexOf(o); 344 if (i < 0) { 345 return false; 346 } 347 remove(i); 348 return true; 349 } 350 351 352 /*** 353 * TODO: document the method 354 * 355 * @return TODO: Describe the Return Value 356 */ 357 public Object[] toArray() { 358 return getList().toArray(); 359 } 360 361 362 /*** 363 * Adds an element to the All attribute of the ListModel object 364 * 365 * @param c The element to be added to the All attribute 366 * @return TODO: Describe the Return Value 367 */ 368 public boolean addAll(Collection c) { 369 boolean result = false; 370 makeActive(false); 371 try { 372 for (Iterator i = c.iterator(); i.hasNext(); ) { 373 result = result | add(i.next()); 374 } 375 } finally { 376 makeActive(true); 377 } 378 fireModelChange(VALUE_CHANGED, null); 379 return result; 380 } 381 382 383 /*** 384 * TODO: document the method 385 * 386 * @param o TODO: Describe the Parameter 387 * @return TODO: Describe the Return Value 388 */ 389 public boolean add(Object o) { 390 if (LOG.isDebugEnabled()) { 391 LOG.debug("add: " + o); 392 } 393 if (!contents.add(o)) { 394 return false; 395 } 396 397 if (propagateModelChanges && o instanceof ModelChangeEventSource) { 398 ((ModelChangeEventSource) o).addModelChangeListener(this); 399 } 400 fireModelChange(VALUE_ADDED, Selector.fromInt(contents.size() - 1)); 401 return true; 402 } 403 404 405 /*** 406 * TODO: document the method 407 * 408 * @param c TODO: Describe the Parameter 409 * @return TODO: Describe the Return Value 410 */ 411 public boolean removeAll(Collection c) { 412 boolean result = false; 413 makeActive(false); 414 try { 415 for (Iterator i = c.iterator(); i.hasNext(); ) { 416 result = result | remove(i.next()); 417 } 418 } finally { 419 makeActive(true); 420 } 421 fireModelChange(VALUE_CHANGED, null); 422 return result; 423 } 424 425 426 /*** 427 * TODO: document the method 428 * 429 * @param c TODO: Describe the Parameter 430 * @return TODO: Describe the Return Value 431 */ 432 public boolean containsAll(Collection c) { 433 return getList().containsAll(c); 434 } 435 436 437 /*** 438 * TODO: document the method 439 */ 440 public void clear() { 441 makeActive(false); 442 try { 443 if (propagateModelChanges) { 444 for (Iterator i = contents.iterator(); i.hasNext(); ) { 445 Object o = i.next(); 446 if (o instanceof ModelChangeEventSource) { 447 ((ModelChangeEventSource) o).removeModelChangeListener(this); 448 } 449 } 450 } 451 contents.clear(); 452 } finally { 453 makeActive(true); 454 } 455 fireModelChange(VALUE_CHANGED, null); 456 } 457 458 459 /*** 460 * Adds an element to the All attribute of the ListModel object 461 * 462 * @param index The element to be added to the All attribute 463 * @param c The element to be added to the All attribute 464 * @return TODO: Describe the Return Value 465 */ 466 public boolean addAll(int index, Collection c) { 467 boolean result = false; 468 makeActive(false); 469 try { 470 for (Iterator i = c.iterator(); i.hasNext(); ) { 471 result = result | add(i.next()); 472 } 473 } finally { 474 makeActive(true); 475 } 476 fireModelChange(VALUE_CHANGED, null); 477 return result; 478 } 479 480 481 /*** 482 * TODO: document the method 483 * 484 * @return TODO: Describe the Return Value 485 */ 486 public int hashCode() { 487 return getList().hashCode(); 488 } 489 490 491 /*** 492 * TODO: document the method 493 * 494 * @param c TODO: Describe the Parameter 495 * @return TODO: Describe the Return Value 496 */ 497 public boolean retainAll(Collection c) { 498 List original = new ArrayList(contents); 499 boolean result = false; 500 makeActive(false); 501 try { 502 for (Iterator i = original.iterator(); i.hasNext(); ) { 503 Object o = i.next(); 504 if (!c.contains(o)) { 505 remove(o); 506 result = true; 507 } 508 } 509 } finally { 510 makeActive(true); 511 } 512 fireModelChange(VALUE_CHANGED, null); 513 return result; 514 } 515 516 517 /*** 518 * TODO: document the method 519 * 520 * @param o TODO: Describe the Parameter 521 * @return TODO: Describe the Return Value 522 */ 523 public boolean equals(Object o) { 524 return getList().equals(o); 525 } 526 527 528 /*** 529 * TODO: document the method 530 * 531 * @param index TODO: Describe the Parameter 532 * @return TODO: Describe the Return Value 533 */ 534 public Object remove(int index) { 535 if (contents == null) { 536 return null; 537 } 538 539 Object oldValue = contents.remove(index); 540 if (propagateModelChanges && oldValue instanceof ModelChangeEventSource) { 541 ((ModelChangeEventSource) oldValue).removeModelChangeListener(this); 542 } 543 if (oldValue != null) { 544 fireModelChange(VALUE_REMOVED, Selector.fromInt(index)); 545 } 546 return oldValue; 547 } 548 549 550 /*** 551 * TODO: document the method 552 * 553 * @param o TODO: Describe the Parameter 554 * @return TODO: Describe the Return Value 555 */ 556 public int lastIndexOf(Object o) { 557 return getList().lastIndexOf(o); 558 } 559 560 561 /*** 562 * TODO: document the method 563 * 564 * @param index TODO: Describe the Parameter 565 * @param o TODO: Describe the Parameter 566 */ 567 public void add(int index, Object o) { 568 getList().add(index, o); 569 if (propagateModelChanges && o instanceof ModelChangeEventSource) { 570 ((ModelChangeEventSource) o).addModelChangeListener(this); 571 } 572 fireModelChange(VALUE_ADDED, Selector.fromInt(index)); 573 } 574 575 576 /*** 577 * TODO: document the method 578 * 579 * @param index TODO: Describe the Parameter 580 * @return TODO: Describe the Return Value 581 */ 582 public ListIterator listIterator(int index) { 583 return getList().listIterator(index); 584 } 585 586 587 /*** 588 * TODO: document the method 589 * 590 * @param o TODO: Describe the Parameter 591 * @return TODO: Describe the Return Value 592 */ 593 public int indexOf(Object o) { 594 return getList().indexOf(o); 595 } 596 597 598 /*** 599 * TODO: document the method 600 * 601 * @return TODO: Describe the Return Value 602 */ 603 public ListIterator listIterator() { 604 return getList().listIterator(); 605 } 606 607 608 /*** 609 * TODO: document the method 610 * 611 * @param fromIndex TODO: Describe the Parameter 612 * @param toIndex TODO: Describe the Parameter 613 * @return TODO: Describe the Return Value 614 */ 615 public List subList(int fromIndex, int toIndex) { 616 return getList().subList(fromIndex, toIndex); 617 } 618 }

This page was automatically generated by Maven